/**
 * 
 */
package es.ats.codington.festival.daos;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import es.ats.codington.festival.domain.Event;
import es.ats.codington.festival.exceptions.DAOException;
import es.ats.codington.festival.interfaces.daos.IEventDAO;
import es.ats.codington.festival.mappers.EventMapper;


/**
 * @author Codington_RED
 *
 */
public class EventDAOImpl implements IEventDAO { 
	
	/**
	 * JdbcTemplate
	 * Properties
	 */
	private JdbcTemplate jdbcTemplateObject;
	private Properties queryProperties;
	
	public int key;
	
	
	
	/**
	 * Default constructor for EventDAOImpl
	 * @param jdbcTemplateObject
	 * @param queryProperties
	 */
	public EventDAOImpl (JdbcTemplate jdbcTemplateObject, Properties queryProperties){
		
		this.jdbcTemplateObject = jdbcTemplateObject;
		this.queryProperties = queryProperties;	
		
	}

	/**
	 * Method that retrieves a list with all the events in it.
	 * @param resultSet
	 * @return events 
	 * @throws SQLException
	 */
	private List<Event> getEventList(ResultSet resultSet) throws SQLException {
		
		List<Event> events = new ArrayList<Event>();
		
		while(resultSet.next()) {	      
		    Event event = new Event();
		
		    event.setEventID(resultSet.getInt("eventId"));
		    event.setName(resultSet.getString("name"));
		    event.setDescription(resultSet.getString("description"));
		    event.setPlace(resultSet.getString("place"));
		    event.setStartEvent(resultSet.getString("startEvent"));
		    event.setEndEvent(resultSet.getString("endEvent"));
		    event.setDayEvent(resultSet.getString("dayEvent"));
		    event.setEventType(resultSet.getString("eventType"));
		    event.setSeatsAvailable(resultSet.getInt("seatsAvailable"));
		    event.setIdPlace(resultSet.getInt("idPlace"));
		 
		    events.add(event);
		    
		}
		
		return events;
	}
	/**
	 * This method obtains a resultSet with the Event List
	 * @param resultSet
	 * @return event
	 * @throws SQLException
	 */
	@Override
	 public Event getEvent(ResultSet resultSet) throws SQLException {
			
			Event event = null;	
			List<Event> events = this.getEventList(resultSet);	
			
			if(!events.isEmpty()) {
			    event = events.get(0);
			    
			}
					
			return event;
		    }  
	/**
	 * selects an event by its id and and visitor ID
	 * @param event
	 * @return eventh
	 * @throws DAOException
	 * @throws SQLException
	 */

	
	@Override
	public boolean getCheckEvent(final Event event) throws DAOException, SQLException {
		
		boolean eventh = false;
		
		List<Event> events = jdbcTemplateObject.query(queryProperties.getProperty("checkEvent"), 
				new PreparedStatementSetter(){

					@Override
					public void setValues(PreparedStatement ps)
							throws SQLException {
						
						ps.setString(1, event.getName());
						ps.setString(2, event.getDescription());
						ps.setString(3, event.getPlace());
						ps.setString(4, event.getStartEvent());
						ps.setString(5, event.getEndEvent());
						ps.setString(6, event.getDayEvent());
						ps.setString(7, event.getEventType());
						ps.setInt(8, event.getSeatsAvailable());
						ps.setInt(9, event.getIdPlace());
						
					}
			
		}, new EventMapper());
		
		if(events.size() == 1){
			
			eventh = true;
		}
		
		return eventh;
		
	}
	
	/**
	 * retrieve a list with all the events.
	 * @return events
	 * @throws DAOException
	 */
	@Override
	public List<Event> showAllEvents() throws DAOException {
		
		
		List<Event> events = jdbcTemplateObject.query(queryProperties.getProperty("allEvents"), 
				new EventMapper());
		
		return events;
		
	}
	
	/**
	 * retrieve a list with all the events and you must pass it the event Name
	 * @param eventname
	 * @return events
	 * @throws DAOException
	 */
	@Override
	public List<Event> showEvents(final Event event) throws DAOException {
		
		
		List<Event> events = jdbcTemplateObject.query(queryProperties.getProperty("searchByEventName"), 
				new PreparedStatementSetter(){

					@Override
					public void setValues(PreparedStatement ps)
							throws SQLException {
						
						ps.setString(1, event.getName());
						
					}
			
		}, new EventMapper());
		
		return events;
		
		
	}
	
	/**
	 * what it makes is to obtain a event by its ID
	 * @param eventId
	 * @return event
	 * @throws DAOException
	 */
	@Override
	public Event getEvent(final int eventId) throws DAOException {
		
		List<Event> events = jdbcTemplateObject.query(queryProperties.getProperty("getEvent"), 
				new PreparedStatementSetter(){

					@Override
					public void setValues(PreparedStatement ps)
							throws SQLException {
						
						 ps.setInt(1, eventId);
						
					}
			
		}, new EventMapper());
		
		return events.get(0);
		
	}
	
	/**
	 * obtain the iD of an specific Event
	 * @param event
	 * @return id
	 * @throws DAOException
	 * @throws SQLException
	 */
	@Override
	public int getIdEvent(final Event event) throws DAOException, SQLException {

		
		int idEvent = 0;
		
		List<Event> events = jdbcTemplateObject.query(queryProperties.getProperty("idEvent"), 
				new PreparedStatementSetter(){

					@Override
					public void setValues(PreparedStatement ps)
							throws SQLException {
						
						ps.setString(1, event.getName());
					    ps.setString(2, event.getStartEvent());
						
					}
			
		}, new EventMapper());
		
		idEvent = events.get(0).getEventID();
		
		
		return idEvent;	

	}
	
	/**
	 * update all the information about an specific Event
	 * @param updateEvent
	 * @return affectedRows
	 * @throws DAOException
	 */
	@Override
	public int updateEvent(final Event updateEvent) throws DAOException {

		Integer affectedRows = 0;
		
		affectedRows = jdbcTemplateObject.update(queryProperties.getProperty("updateEvent"), 
				new PreparedStatementSetter(){

					@Override
					public void setValues(PreparedStatement ps)
							throws SQLException {
						
						 ps.setString(1, updateEvent.getName());
						 ps.setString(2, updateEvent.getDescription());
						 ps.setString(3, updateEvent.getPlace());
						 ps.setString(4, updateEvent.getStartEvent());
						 ps.setString(5, updateEvent.getEndEvent());
						 ps.setString(6, updateEvent.getDayEvent());
						 ps.setString(7, updateEvent.getEventType());
						 ps.setInt(8, updateEvent.getSeatsAvailable());
						 ps.setInt(9, updateEvent.getIdPlace());
						 ps.setInt(10, updateEvent.getEventID());
						
					}
		});
		
		return affectedRows;
		
		
	}
	
	/**
	 * what this method tries to perform is a insertion of an event into the database table.
	 * @param insertEvent
	 * @return insertEv
	 * @throws DAOException
	 */
	@Override
	public boolean insertEvent(final Event insertEvent) throws DAOException {
		
		boolean insertEv = false;
		Integer affectedRows = 0;
		
		KeyHolder keyHolder = new GeneratedKeyHolder();
		affectedRows = jdbcTemplateObject.update(new PreparedStatementCreator() {
			public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
				PreparedStatement ps =
                        conn.prepareStatement(queryProperties.getProperty("insertEvent"), PreparedStatement.RETURN_GENERATED_KEYS);
				 		ps.setString(1, insertEvent.getName());
				 		ps.setString(2, insertEvent.getDescription());
				 		ps.setString(3, insertEvent.getPlace());
				 		ps.setString(4, insertEvent.getStartEvent());
				 		ps.setString(5, insertEvent.getEndEvent());
				 		ps.setString(6, insertEvent.getDayEvent());
				 		ps.setString(7, insertEvent.getEventType());
				 		ps.setInt(8, insertEvent.getSeatsAvailable());
				 		ps.setInt(9, insertEvent.getIdPlace());
						
						return ps;
			}
			
		}, keyHolder);
		
		key = keyHolder.getKey().intValue();
		insertEvent.setEventID(key);
		
		if (affectedRows > 0) {
			insertEv = true;
		}
		
		return insertEv;
	
	}
	
	/**
	 * update the availability of the event 
	 * @param event
	 * @return affectedRows
	 * @throws DAOException
	 */
	@Override
	public int updateSeatsEventInc(final Event event) throws DAOException {
		
		
		Integer affectedRows = 0;
		
		affectedRows = jdbcTemplateObject.update(queryProperties.getProperty("updateSeatsEventInc"), 
				new PreparedStatementSetter(){

					@Override
					public void setValues(PreparedStatement ps)
							throws SQLException {
						
						 ps.setInt(1, event.getEventID());	
						
					}
		});
		
		return affectedRows;
	
	}  
	
	/**
	 * update the availability of the event 
	 * @param event
	 * @return affectedRows
	 * @throws DAOException
	 */
	@Override
	public int updateSeatsEventDec(final Event event) throws DAOException {
		
		Integer affectedRows = 0;
		
		affectedRows = jdbcTemplateObject.update(queryProperties.getProperty("updateSeatsEventDec"), 
				new PreparedStatementSetter(){

					@Override
					public void setValues(PreparedStatement ps)
							throws SQLException {
						
						 ps.setInt(1, event.getEventID());	
						
					}
		});
		
		return affectedRows;
	}
	

}
